import BigNumber from 'bignumber.js';
import {DEFAULT_DISPLAY_NAME} from '../constants';
import CryptoJS from 'crypto-js';
import {format} from 'date-fns';
import {PublicKey} from '@solana/web3.js';
import Config from 'react-native-config';

export function parseUnits(amount: string, decimals: number) {
  return BigNumber(amount)
    .multipliedBy(BigNumber(10).pow(BigNumber(decimals)))
    .toFixed(0);
}

export function parseValue(
  value: string | number,
  decimals: number,
  fixed?: number,
): string {
  return BigNumber(value)
    .dividedBy(BigNumber(10).pow(decimals))
    .toFixed(fixed ?? decimals, BigNumber.ROUND_FLOOR);
}

export function generatePasskeyTitle(userName?: string) {
  const currentDate = new Date();

  const year = currentDate.getFullYear();
  const month = String(currentDate.getMonth() + 1).padStart(2, '0'); // getMonth() returns 0-11, so add 1
  const day = String(currentDate.getDate()).padStart(2, '0');
  const hours = String(currentDate.getHours()).padStart(2, '0');
  const minutes = String(currentDate.getMinutes()).padStart(2, '0');

  const formattedDate = `${year}/${month}/${day} ${hours}:${minutes}`;

  const passkeyTitle = `${
    userName ? userName : DEFAULT_DISPLAY_NAME
  }@UpNetwork (${formattedDate})`;

  return passkeyTitle;
}

export function toShortAddress(value: string, len: number = 10) {
  if (value.length <= len) {
    return value;
  }

  let first = '';
  let second = '';
  const valueList = value.split('');
  for (let i = 0; i < valueList.length; i++) {
    if (i < len) {
      first = first + valueList[i];
    }
    if (i > value.length - len) {
      second = second + valueList[i];
    }
  }

  return `${first}***${second}`;
}

export function parseShortCardNumber(
  cardNumber: string,
  fixed: number = 4,
): string {
  if (cardNumber.length <= fixed) {
    return cardNumber;
  }

  const cardNumberList = cardNumber.split('');
  const rCardNumberList = cardNumberList.reverse();
  const resultList = [];
  for (let i: number = 0; i < fixed; i++) {
    resultList.push(rCardNumberList[i]);
  }

  return resultList.reverse().join('');
}

export function parseCardNumberMask(cardNumber: string) {
  return `•••• •••• •••• ${parseShortCardNumber(cardNumber)}`;
}

export function hashString(input: string): string {
  return CryptoJS.SHA256(input).toString(CryptoJS.enc.Hex);
}

export function formatTimestamp(
  ts: number,
  fmtString: string = 'yyyy-MM-dd HH:mm:ss',
): string {
  return format(new Date(ts), fmtString);
}

export const formatCurrency = (
  amount: number,
  currency: string,
  minDecimals: number,
  maxDecimals: number,
) => {
  return new Intl.NumberFormat('en-US', {
    style: 'currency',
    currency: currency,
    currencyDisplay: 'symbol',
    minimumFractionDigits: minDecimals,
    maximumFractionDigits: maxDecimals,
  }).format(amount);
};

export function calTokenValue(
  tokenAmount: string | number,
  tokenPrice: string,
  fixed: number = 6,
) {
  const value = BigNumber(tokenAmount)
    .multipliedBy(BigNumber(tokenPrice))
    .toNumber();
  return formatCurrency(value, 'SGD', 2, fixed);
}

export const formatNumber = (
  value: number | string,
  minDecimals: number,
  maxDecimals: number,
) => {
  return new Intl.NumberFormat('en-US', {
    minimumFractionDigits: minDecimals,
    maximumFractionDigits: maxDecimals,
  }).format(Number(value));
};

export const isValidSolanaAddress = (address: string) => {
  try {
    new PublicKey(address);
    return true;
  } catch (error) {
    return false;
  }
};

export function generateServerSig(userName: string, timestamp: string): string {
  return `0x${CryptoJS.SHA256(`${userName}${timestamp}`).toString(
    CryptoJS.enc.Hex,
  )}`;
}

export function parseSolanaScanTxUrl(txHash: string) {
  if (Config.APP_MODE == 'prod') {
    return `${Config.SOLANA_SCAN}/tx/${txHash}`;
  } else {
    return `${Config.SOLANA_SCAN}/tx/${txHash}?cluster=devnet`;
  }
}
